package com.hkzhao.shixun.service.impl;
import cn.hutool.core.lang.Pair;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.hkzhao.shixun.common.api.CommonResult;
import com.hkzhao.shixun.common.utils.JwtTokenUtil;
import com.hkzhao.shixun.common.utils.TokenTranslate;
import com.hkzhao.shixun.common.utils.TokenUtil;
import com.hkzhao.shixun.config.QiniuConfig;
import com.hkzhao.shixun.mbg.mapper.*;
import com.hkzhao.shixun.mbg.model.*;
import com.hkzhao.shixun.service.AdminService;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.Date;
import java.util.List;
@Service
public class AdminServiceImpl implements AdminService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(AdminServiceImpl.class);
    @Autowired(required = false)
    private UserDetailsService userDetailsService;
    @Autowired(required = false)
    private PasswordEncoder passwordEncoder;
    @Autowired(required = false)
    private JwtTokenUtil jwtTokenUtil;
    @Autowired(required=false)
    private AdminMapper adminMapper;
    @Autowired(required=false)
    private UserpermissionMapper userpermissionMapper;
    @Autowired(required=false)
    private CoreuserMapper coreuserMapper;
    @Autowired(required=false)
    private TokenTranslate tokenTranslate;
    @Autowired(required=false)
    private ActivityMapper activityMapper;
    @Autowired(required=false)
    private LotteryrecordMapper lotteryrecordMapper;
    @Autowired(required=false)
    private PrizeMapper prizeMapper;
    @Value("${jwt.adminAuthority}")
    private String adminAuthority;
    @Override
    public CommonResult register(String username, String password)
    {
        if(username.length()==0){
            return CommonResult.failed("用户名不能为空");
        }
        if(password.length()==0){
            return CommonResult.failed("密码不能为空");
        }
        if (adminMapper.selectByPrimaryKey(username)!=null) return CommonResult.failed("用户名重复");
        String token_id =TokenUtil.GetGUID();
        Admin admin = new Admin();
        Userpermission userpermission = new Userpermission();
        Coreuser coreUser = new Coreuser();
        admin.setUsername(username);admin.setPassword(passwordEncoder.encode(password));admin.setTokenid(token_id);
        userpermission.setCreatetime(new Date());userpermission.setValue(adminAuthority);userpermission.setTokenid(token_id);
        coreUser.setPosition("1");coreUser.setTokenid(token_id);coreUser.setUsername(username);
        adminMapper.insert(admin);
        userpermissionMapper.insert(userpermission);
        coreuserMapper.insert(coreUser);
        return CommonResult.success("注册管理员用户成功");
    }

    @Override
    public String login(String username, String password)
    {
        String token=null;
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            token = jwtTokenUtil.generateToken(userDetails);
        }catch (AuthenticationException e){
            LOGGER.warn("登陆异常:{}",e.getMessage());
        }
        return token;
    }
    @Override
    public String getAdminbytoken(HttpServletRequest httpServletRequest)
    {
        return tokenTranslate.GetUsernameByHeader(httpServletRequest);
    }
    @Override
    public Pair<String,String> newActivity(String id, String tag, String title, Date start, Date end, Double ci, String description, String uname, Integer participate, String drawstype, Integer drawsnum, String status)
    {
        Activity act=new Activity();
        String proc="http://";
        String host="39.108.172.82:80";
        String url=proc+host+"/#/act?actid="+id;
        act.setActivityid(id);act.setTag(tag);act.setTitle(title);act.setStartdate(start);act.setEnddate(end);act.setCostintegral(ci);act.setUrl(url);act.setQrcode(genqrbase64(url));
        act.setCreatorname(uname);act.setStatus(status);act.setParticipatenum(participate);act.setDrawstype(drawstype);act.setDrawsnum(drawsnum);act.setDescription(description);
        activityMapper.insert(act);
        return new Pair<>(act.getUrl(),act.getQrcode());
    }
    @Override
    public String addPrize(String prizeid,String activityid, String level, Double odd, String description, Integer nums, String url)
    {
        Prize prize=new Prize();
        prize.setActivityid(activityid);prize.setLevel(level);prize.setOdd(odd);prize.setDescription(description);prize.setNums(nums);prize.setUrl(url);
        prize.setHaslotterynum(0);prize.setPrizeid(prizeid);
        prizeMapper.insert(prize);
        return prize.getPrizeid();
    }
    @Autowired
    QiniuConfig qiniuConfig;
    @Override
    public String pic2qiniu(InputStream file, String key)
    {
        Configuration cfg = new Configuration(Zone.zone2());
        UploadManager uploadManager=new UploadManager(cfg);
        try {
            Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
            String upToken = auth.uploadToken(qiniuConfig.getBucket());
            try {
                Response response = uploadManager.put(file, key, upToken, null, null);
                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                String returnPath = qiniuConfig.getPath() + "/" + putRet.key;
                return returnPath;
            } catch (QiniuException ex) {
                Response r = ex.response;
                System.err.println(r.toString());
                try {
                    System.err.println(r.bodyString());
                } catch (QiniuException ex2) {
                    return "fail";
                }
                return "fail";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }
    @Override
    public String genqrbase64(String url)
    {
        try{
            QRCodeWriter qrCodeWriter=new QRCodeWriter();
            BitMatrix bitMatrix=qrCodeWriter.encode(url, BarcodeFormat.QR_CODE,600,600);
            ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix,"PNG",byteArrayOutputStream);
            Base64.Encoder encoder=Base64.getEncoder();
            String b64=encoder.encodeToString(byteArrayOutputStream.toByteArray());
            b64="data:image/png;base64,"+b64;
            return b64;
        }catch(Exception e)
        {
            System.out.println(e.getStackTrace());
            return "genfail";
        }
    }
    @Override
    public List<Lotteryrecord> getRecordby(String username, String actid, String recid, int pageNum, int pageSize)
    {
        LotteryrecordExample lotteryrecordExample=new LotteryrecordExample();
        LotteryrecordExample.Criteria r=lotteryrecordExample.createCriteria();r.andActivityidIsNotNull();
        if (username!=null) r.andUsernameEqualTo(username);
        if (actid!=null) r.andActivityidEqualTo(actid);
        if (recid!=null) r.andRecordidEqualTo(recid);
        PageHelper.startPage(pageNum,pageSize);
        return lotteryrecordMapper.selectByExample(lotteryrecordExample);
    }
    @Override
    public List<Activity> getActivityby(String actid, String tag, String title,String status, int pageNum, int pageSize)
    {
        ActivityExample activityExample=new ActivityExample();
        ActivityExample.Criteria r=activityExample.createCriteria();r.andActivityidIsNotNull();
        if (actid!=null) r.andActivityidEqualTo(actid);
        if (tag!=null) r.andTagEqualTo(tag);
        if (title!=null) r.andTitleEqualTo(title);
        if (title!=status) r.andStatusEqualTo(status);
        PageHelper.startPage(pageNum,pageSize);
        return activityMapper.selectByExampleWithBLOBs(activityExample);
    }
    @Override
    public List<Prize> getPrizeby(String actid)
    {
        PrizeExample prizeExample=new PrizeExample();
        PrizeExample.Criteria r=prizeExample.createCriteria();r.andPrizeidIsNotNull();
        if (actid!=null) r.andActivityidEqualTo(actid);
        return prizeMapper.selectByExample(prizeExample);
    }
    @Override
    public String actActivity(String actid)
    {
        ActivityExample activityExample=new ActivityExample();
        ActivityExample.Criteria r=activityExample.createCriteria();r.andActivityidEqualTo(actid);
        List<Activity> old=activityMapper.selectByExampleWithBLOBs(activityExample);
        if (old.size()==0) return "Wrong actid";
        Activity tmp=old.get(0);tmp.setStatus("1");
        activityMapper.updateByExampleWithBLOBs(tmp,activityExample);
        return "ok";
    }
    @Override
    public String endActivity(String actid)
    {
        ActivityExample activityExample=new ActivityExample();
        ActivityExample.Criteria r=activityExample.createCriteria();r.andActivityidEqualTo(actid);
        List<Activity> old=activityMapper.selectByExampleWithBLOBs(activityExample);
        if (old.size()==0) return "Wrong actid";
        Activity tmp=old.get(0);tmp.setStatus("2");
        activityMapper.updateByExampleWithBLOBs(tmp,activityExample);
        return "ok";
    }
    @Override
    public Boolean delActivity(String actid)
    {
        ActivityExample activityExample=new ActivityExample();
        ActivityExample.Criteria r=activityExample.createCriteria();r.andActivityidEqualTo(actid);
        List<Activity> old=activityMapper.selectByExampleWithBLOBs(activityExample);
        if (old.size()==0) return Boolean.FALSE;
        PrizeExample prizeExample=new PrizeExample();
        PrizeExample.Criteria rr=prizeExample.createCriteria();rr.andActivityidEqualTo(actid);
        List<Prize> lk=prizeMapper.selectByExample(prizeExample);
        if (lk.size()!=0) prizeMapper.deleteByExample(prizeExample);
        activityMapper.deleteByExample(activityExample);
        return Boolean.TRUE;
    }
    @Override
    public String modifyActivity(String actid, String title, Double costintegral, Integer drawsnum)
    {
        ActivityExample activityExample=new ActivityExample();
        ActivityExample.Criteria r=activityExample.createCriteria();r.andActivityidEqualTo(actid);
        List<Activity> old=activityMapper.selectByExampleWithBLOBs(activityExample);
        if (old.size()==0) return "Wrong actid";
        Activity tmp=old.get(0);
        if (title!=null) tmp.setTitle(title);
        if (costintegral!=null) tmp.setCostintegral(costintegral);
        if (drawsnum!=null) tmp.setDrawsnum(drawsnum);
        activityMapper.updateByExampleWithBLOBs(tmp,activityExample);
        return "ok";
    }
}
